function [data_mat, data_mat_end_of_quarter, pos] =aggregate_spread_data(data,timeline)
% function [data_mat, data_mat_end_of_quarter] =aggregate_spread_data(data,timeline)
% aggregate daily spread to quarterly data
% Inputs:
%       data     [T by 4] matrix     daily data matrix with columns [date yield benchmark_yield spread]
%       timeline [N by 1] vector     timeline vector with format 2001.25
%                                    for 2001Q2 
% Outputs:
%       data_mat                    [N by 4] matrix     data matrix with average spreads with columns [date yield benchmark_yield spread]
%       data_mat_end_of_quarter     [N by 4] matrix     data matrix with end of quarter spreads with columns [date yield benchmark_yield spread]
%       pos                         structure           structure with positions of variables in matrix                                     

% Copyright (C) 2014-19 Benjamin Born and Johannes Pfeifer 
%
% This is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This code is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% For a copy of the licencse,
% see <http://www.gnu.org/licenses/>.


if size(data,2)~=4
    error('Input dimensions do not agree.')
end

pos.date=1;
pos.yield=2;
pos.bench=3;
pos.spread=4;

data_mat=[timeline,NaN(length(timeline),3)];
data_mat_end_of_quarter=[timeline,NaN(length(timeline),3)];
% yields=[timeline,NaN(length(timeline),1)];
% bench=[timeline,NaN(length(timeline),1)];

% get dates in year month day etc format
date_matrix=datevec(data(:,pos.date));
% make sure that at least one month is cut off at the end to account for
% low liquidity etc.
date_matrix(end-30:end,:)=[];


% define variable positions in date matrix
year_pos=1;
month_pos=2;
% read out first and last year and quarter
begin_year=date_matrix(1,year_pos);
end_year=date_matrix(end,year_pos);
begin_quarter=ceil(date_matrix(1,month_pos)/3);
end_quarter=ceil(date_matrix(end,month_pos)/3);

%span timeline
timeline_spreads=(begin_year+(begin_quarter-1)*0.25:.25:end_year+(end_quarter-1-2)*0.25)';
temp_data_mat=[timeline_spreads, NaN(length(timeline_spreads),1)];
temp_data_mat_end_of_quarter=[timeline_spreads, NaN(length(timeline_spreads),1)];

begin_quarter_for_mean=datenum([num2str((begin_quarter)*3-2),'/01/',num2str(begin_year)]);
for ii=begin_year+(begin_quarter-1)*0.25:.25:end_year+(end_quarter-1-2)*0.25
    if mod(ii,1)/0.25==3 
        end_quarter_for_mean=datenum(['01/01/',num2str(floor(ii)+1)]);
    else 
        end_quarter_for_mean=datenum([num2str((mod(ii,1)/0.25+1)*3+1),'/01/',num2str(floor(ii))]);
    end
    data_temp=data(data(:,pos.date)>=begin_quarter_for_mean & data(:,pos.date)<end_quarter_for_mean,:);
    if ~isempty(data_temp)
        temp_data_mat(timeline_spreads(:,1)==ii,pos.spread)=mean(data(data(:,pos.date)>=begin_quarter_for_mean & data(:,pos.date)<end_quarter_for_mean,pos.spread));
        temp_data_mat(timeline_spreads(:,1)==ii,pos.yield)=mean(data(data(:,pos.date)>=begin_quarter_for_mean & data(:,pos.date)<end_quarter_for_mean,pos.yield));
        temp_data_mat(timeline_spreads(:,1)==ii,pos.bench)=mean(data(data(:,pos.date)>=begin_quarter_for_mean & data(:,pos.date)<end_quarter_for_mean,pos.bench));
        temp_data_mat_end_of_quarter(timeline_spreads(:,1)==ii,pos.spread)=data_temp(end,pos.spread);
        temp_data_mat_end_of_quarter(timeline_spreads(:,1)==ii,pos.yield)=data_temp(end,pos.yield);
        temp_data_mat_end_of_quarter(timeline_spreads(:,1)==ii,pos.bench)=data_temp(end,pos.bench);
    end
    begin_quarter_for_mean=end_quarter_for_mean;
end
% yields(ismember(data_mat(:,1),temp_data_mat(:,1)),end)=temp_data_mat(:,3);
% bench(ismember(data_mat(:,1),temp_data_mat(:,1)),end)=temp_data_mat(:,4);
data_mat(ismember(data_mat(:,1),temp_data_mat(:,1)),:)=temp_data_mat;
data_mat_end_of_quarter(ismember(data_mat(:,1),temp_data_mat(:,1)),:)=temp_data_mat_end_of_quarter;

if any(diff(data_mat(:,1))<0.2499) || any(diff(data_mat(:,1))>0.25001) || any(diff(data_mat_end_of_quarter(:,1))<0.2499) || any(diff(data_mat_end_of_quarter(:,1))>0.25001)
    error('Writing to data matrix was not successful. There is a time gap.')
end